﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Diagnostics;
using System.Linq;

public partial class EventLogs : System.Web.UI.Page
{
    private const int PageSize = 40;
    private int page = 1;
    private string sortField = "Time";
    private SortDirection sortDirection = SortDirection.Descending;

    public int PagesCount { get; private set; }

    public int PageNumber
    {
        get
        {
            return page;
        }
        set
        {
            ViewState["page"] = value;
            page = value;
        }
    }

    public string SortField
    {
        get
        {
            return sortField;
        }
        set
        {
            ViewState["sortField"] = value;
            sortField = value;
        }
    }

    public SortDirection SortDirection
    {
        get
        {
            return sortDirection;
        }
        set
        {
            ViewState["sortDirection"] = value;
            sortDirection = value;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (ViewState["page"] != null)
        {
            page = (int)ViewState["page"];
        }

        if (ViewState["sortField"] != null)
        {
            sortField = (string)ViewState["sortField"];
        }

        if (ViewState["sortDirection"] != null)
        {
            sortDirection = (SortDirection)ViewState["sortDirection"];
        }
               

        LoadEntries();
    }

    protected void ddlPage_Load(object sender, EventArgs e)
    {
        var ctl = (DropDownList)sender;

        if (!IsPostBack)
        {                        
            ctl.DataSource = Enumerable.Range(1, PagesCount);
            ctl.DataBind();
        }
        else
        {
            if (PagesCount != ctl.Items.Count)
            {
                ctl.DataSource = Enumerable.Range(1, PagesCount);
                ctl.DataBind();
            }
        }
    }

    private void LoadEntries()
    {
        var logName = Request.QueryString["log"];

        var log = new EventLog(logName);

        Title = string.Format("Event log:{0}", log.LogDisplayName);
       
        var entries = from EventLogEntry entry in log.Entries                       
                       select entry; 


        if (!IsPostBack)
        {
            var q = entries.Select(i => i.Source);
            ddlSource.DataSource = q.Distinct();
            ddlSource.DataBind();

            var q2 = from e in entries
                     where e.UserName != null
                     select e.UserName;
            ddlUser.DataSource = q2.Distinct();
            ddlUser.DataBind();                 
        }

        if (ddlSource.SelectedIndex != 0)
        {
            entries = entries.Where(entry => entry.Source == ddlSource.SelectedValue);
        }

        switch (ddlUser.SelectedIndex)
        {
            case 0:
                break;
            case 1:
                entries = entries.Where(entry => entry.UserName == null);
                break;
            default:
                entries = entries.Where(entry => entry.UserName == ddlUser.SelectedValue);
                break;
        }        

        foreach (ListItem item in cblEntryTypes.Items)
        {
            var t = (EventLogEntryType)Enum.Parse(typeof(EventLogEntryType), item.Value);
            if (!item.Selected)
            {
                entries = entries.Where(entry => entry.EntryType != t);
            }
        }

        PagesCount = (int)Math.Ceiling((double)entries.Count() / (double)PageSize);

        switch (SortField)
        {
            case "Type":
                entries = entries.OrderBy(entry => entry.EntryType);
                break;

            case "Time":
                entries = entries.OrderBy(entry => entry.TimeWritten);
                break;

            case "Source":
                entries = entries.OrderBy(entry => entry.Source);
                break;

            case "User":
                entries = entries.OrderBy(entry => entry.UserName);
                break;

            case "Machine":
                entries = entries.OrderBy(entry => entry.MachineName);
                break;
        }

        if (SortDirection == SortDirection.Descending)
        {
            entries = entries.Reverse();
        }

        entries = entries.Skip((PageNumber - 1) * PageSize);
        entries = entries.Take(PageSize);

        lvEvents.DataSource = entries;
        lvEvents.DataBind();
    }

    protected void changePage(object sender, CommandEventArgs e)
    {
        PageNumber = int.Parse(e.CommandArgument.ToString());        
        ddlPage.SelectedIndex = PageNumber - 1;
        LoadEntries();
    }


    protected void ddlPage_SelectedIndexChanged(object sender, EventArgs e)
    {
        changePage(sender, new CommandEventArgs("changePage", Int32.Parse(ddlPage.SelectedValue)));        
    }

    protected void lbLast_Load(object sender, EventArgs e)
    {
        var ctl = (LinkButton)sender;
        ctl.CommandArgument = PagesCount.ToString();
    }

    protected void lbPrev_Load(object sender, EventArgs e)
    {
        var ctl = (LinkButton)sender;
        ctl.CommandArgument = (PageNumber > 1 ? PageNumber - 1 : 1).ToString();
    }

    protected void lbNext_Load(object sender, EventArgs e)
    {
        var ctl = (LinkButton)sender;
        ctl.CommandArgument = (PageNumber < PagesCount ? PageNumber+1 : PagesCount).ToString();
    }

    protected void Sort(object sender,CommandEventArgs e)
    {
        var n = e.CommandArgument.ToString();

        if (n == SortField)
        {
            switch (SortDirection)
            {
                case SortDirection.Ascending:
                    SortDirection = SortDirection.Descending;
                    break;
                case SortDirection.Descending:
                    SortDirection = SortDirection.Ascending;
                    break;
            }
        }
        else
        {
            SortField = n;
            SortDirection = SortDirection.Ascending;
        }
        
        LoadEntries();
    }
    protected void cblEntryTypes_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            var ctl = (CheckBoxList)sender;
            foreach (var item in Enum.GetNames(typeof(EventLogEntryType)))
            {
                ctl.Items.Add(new ListItem()
                {
                    Value = item,
                    Text = item,
                    Selected = true
                });
            }            
        }
    }
    protected void btnApplyFilter_Click(object sender, EventArgs e)
    {
        LoadEntries();
    }

    protected string GetMoreUrl(object dataItem)
    {
        var e = (EventLogEntry)dataItem;
        return string.Format("javascript:more({0},'{1}')", e.Index, Request.QueryString["log"]);
    }
}
